package ig.finanzas;

import ig.util.excepciones.DatoInvalidoExcepcion;

/**
 * Modela la Modalidad de una tasa. En terminos generales una modalidad hace 
 * referencia a cual es el periodo de la tasa, si es anticipada o vencida, y 
 * si es nominal o no.
 * @author lfgarcia
 */
public class Modalidad {
	
	public static final char PERIODO = 'P';
	public static final char PERIODO_QUINCENAL = 'Q';
	public static final char PERIODO_MES = 'M';
	public static final char PERIODO_BIMESTRE = 'B';
	public static final char PERIODO_TRIMESTRE = 'T';
	public static final char PERIODO_SEMESTRE = 'S';
	public static final char PERIODO_ANO = 'A';
	public static final char MODO_ANTICIPADO = 'A';
	public static final char MODO_VENCIDO = 'V';	
	
	/**
	 * Registra el periodo o tiempo de la expresion (Anual, Semestral, etc).
	 * @uml.property  name="periodo"
	 */
	private char periodo;
	/**
	 * Registra el modo de la expresion (anticipado o vencido).
	 * @uml.property  name="modo"
	 */
	private char modo;
	/**
	 * Registra si la modalidad es nominal, en caso contrario se considera como efectiva.
	 * @uml.property  name="nominal"
	 */
	private boolean nominal;
	/**
	 * Registra el numero de dias del periodo especificado.
	 * @uml.property  name="numdiasPeriodo"
	 */
	private int numdiasPeriodo;
	
	/**
	 * Constructor de la clase que recibe los parametros individuales de la modalidad.
	 * @param periodo Especifica el periodo o el tiempo que maneja la modalidad.
	 * @param modo Especifica el modo de la modalidad (anticipado o vencido).
	 * @param nominal Especifica si la modalidad es nominal, en caso contrario se asume como efectiva.
	 * @throws DatoInvalidoExcepcion Si el valor del periodo o del modo no es valido.
	 */
	public Modalidad( char periodo, char modo, boolean nominal ) throws DatoInvalidoExcepcion{
		
		validarValoresModalidad( periodo, modo );
		
		this.periodo = periodo;
		this.modo = modo;
		this.nominal = nominal;
	}
	
	/**
	 * Constructor de la clase que recibe una cadena donde vienen especificados tanto el periodo
	 * como el modo de la modalidad.
	 * @param modalidad
	 * @param nominal Especifica si la modalidad es nominal, en caso contrario se asume como efectiva.
	 * @throws DatoInvalidoExcepcion Si el valor del periodo o del modo no es valido.
	 */
	public Modalidad( String modalidad, boolean nominal ) throws DatoInvalidoExcepcion{

                modalidad=modalidad.trim();
		if (modalidad.length()!=2) throw new DatoInvalidoExcepcion("El valor de la modalidad especificada debe ser de exactamente dos caracteres : ["+modalidad+"]");
		
		validarValoresModalidad( (char) modalidad.getBytes()[0], (char)modalidad.getBytes()[1] );
		
		this.periodo = (char) modalidad.getBytes()[0];
		this.modo = (char)modalidad.getBytes()[1];
		this.nominal = nominal;
	}
	
	/**
	 * Constructor de la clase para generar objetos Modalidad de cuyo periodo sea PERIODO.
	 * @param numdiasperiodo Numero de dias del periodo
	 * @param modo Especifica el modo de la modalidad (anticipado o vencido).
	 * @param nominal Especifica si la modalidad es nominal, en caso contrario se asume como efectiva.
	 * @throws DatoInvalidoExcepcion
	 */
	public Modalidad( int numdiasperiodo, char modo, boolean nominal) throws DatoInvalidoExcepcion{
		
		//Solo interesa validar el modo de la expresion.
		validarValoresModalidad( PERIODO_ANO, modo );
		
		this.periodo = PERIODO;
		this.numdiasPeriodo = numdiasperiodo;
		this.modo = modo;
		this.nominal = nominal;
		
	}

	/**
	 * @return  Returns the periodo.
	 * @uml.property  name="periodo"
	 */
	public char getPeriodo() {
		return periodo;
	}

	/**
	 * @return  Returns the modo.
	 * @uml.property  name="modo"
	 */
	public char getModo() {
		return modo;
	}

	public boolean esNominal(){
		return nominal;
	}
	
	public int getNumDiasPeriodo(){
		return numdiasPeriodo;
	}
	
	private void validarValoresModalidad( char periodo, char modo ) 
	throws DatoInvalidoExcepcion{
		
		if (!(periodo == PERIODO || periodo == PERIODO_QUINCENAL || periodo == PERIODO_MES 
				|| periodo == PERIODO_BIMESTRE || periodo == PERIODO_TRIMESTRE 
				|| periodo == PERIODO_SEMESTRE || periodo == PERIODO_ANO ))
			throw new DatoInvalidoExcepcion( "El valor del periodo de la modalidad no es valido.");
		
		if (!(modo == MODO_ANTICIPADO || modo == MODO_VENCIDO ))
			throw new DatoInvalidoExcepcion( "El valor del modo de la modalidad no es valido.");
		
		if (periodo == PERIODO)
			numdiasPeriodo = 0;
		if (periodo == PERIODO_QUINCENAL)
			numdiasPeriodo = 15;
		else if (periodo == PERIODO_MES)
			numdiasPeriodo = 30;
		else if (periodo == PERIODO_BIMESTRE)
			numdiasPeriodo = 60;
		else if (periodo == PERIODO_TRIMESTRE)
			numdiasPeriodo = 90;
		else if (periodo == PERIODO_SEMESTRE)
			numdiasPeriodo = 180;
		else if (periodo == PERIODO_ANO)
			numdiasPeriodo = 360;
	}
	
	public String toString(){
		return ""+periodo+modo;
	}

}
